/**
 * 
 */
package com.sidom.movieIndexer.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.sidom.movieIndexer.domain.Movie;
import com.sidom.movieIndexer.domain.file.MovieFile;
import com.sidom.movieIndexer.domain.file.MovieFileCleanedFileNameComparator;
import com.sidom.movieIndexer.domain.google.GoogleSearchResult;
import com.sidom.movieIndexer.domain.google.GoogleSearchResultImdbUrlComparator;

/**
 * Extra collection utility class. Could not find this kind of functionality in
 * any other collection library.
 * See: http://stackoverflow.com/questions/1801459/algorithm-how-to-delete-duplicate-elements-in-a-list-efficiently
 * 
 * @author Siebe
 */
public class CollectionUtils {
	/**
	 * Remove the duplicates from the {@link List} of {@link Movie}s based on
	 * the {@link MovieFile}. The {@link MovieFile} is a duplicate when the
	 * {@link MovieFile#getCleanedFileName()} is the same.
	 * 
	 * @param movies
	 *            The {@link List} of {@link Movie}s to remove the duplicates
	 *            from.
	 * @return The {@link List} of {@link Movie}s without duplicates.
	 */
	public static List<Movie> removeDuplicateMovieFiles(List<Movie> movies) {
		Collections.sort(movies, new MovieFileCleanedFileNameComparator());
		List<Movie> moviesWithoutCleanedFileNameDuplicates = new ArrayList<Movie>();
		String prev = null;
		for (Movie movie : movies) {
			if (!movie.getMovieFile().getCleanedFileName().equals(prev)) {
				moviesWithoutCleanedFileNameDuplicates.add(movie);
			}
			prev = movie.getMovieFile().getCleanedFileName();
		}
		return moviesWithoutCleanedFileNameDuplicates;
	}

	/**
	 * Remove the duplicates from the {@link List} of {@link Movie}s based on
	 * the {@link GoogleSearchResult}. The {@link GoogleSearchResult} is a
	 * duplicate when the {@link GoogleSearchResult#getImdbUrl()} is the same.
	 * 
	 * @param movies
	 *            The {@link List} of {@link Movie}s to remove the duplicates
	 *            from.
	 * @return The {@link List} of {@link Movie}s without duplicates.
	 */
	public static List<Movie> removeDuplicateGoogleSearchResults(List<Movie> movies) {
		Collections.sort(movies, new GoogleSearchResultImdbUrlComparator());
		List<Movie> moviesWithoutImdbUrlDuplicates = new ArrayList<Movie>();
		String previousImdbUrl = null;
		for (Movie movie : movies) {
			if (canBeAddedToMoviesList(movie.getGoogleSearchResult().getImdbUrl(), previousImdbUrl)) {
				moviesWithoutImdbUrlDuplicates.add(movie);
			}
			previousImdbUrl = movie.getGoogleSearchResult().getImdbUrl();
		}
		return moviesWithoutImdbUrlDuplicates;
	}
	
	/**
	 * Check if the {@link Movie} can be added to the {@link List} of unique {@link Movie}s based on the imdbUrl.
	 * @param imdbUrl The imdbUrl.
	 * @param prevImdbUrl The previous imdbUrl in the list.
	 * @return True if the imdb url is empty or null OR the imdbUrl is different from the previous imdbUrl.
	 *         False all other cases.
	 */
	private static boolean canBeAddedToMoviesList(String imdbUrl, String prevImdbUrl){
		if (StringUtils.isEmpty(imdbUrl) || !imdbUrl.equals(prevImdbUrl)) {
			return true;
		}
		return false;
	}
}
